import java.util.Arrays;
import java.util.Stack;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Admin
 * Date: 2022-05-29
 * Time: 15:31
 */
public class TestDemo {
    public static void quickSortSet(int[] array) {
        Stack<Integer> stack = new Stack<>();
        int left = 0;
        int right = array.length-1;

        int pivot = partition2(array,left,right);

        if(pivot > left+1) {
            stack.push(left);
            stack.push(pivot-1);
        }

        if(pivot < right-1) {
            stack.push(pivot+1);
            stack.push(right);
        }

        while(!stack.empty()) {
            right = stack.pop();
            left = stack.pop();

            pivot = partition2(array,left,right);

            if(pivot > left+1) {
                stack.push(left);
                stack.push(pivot-1);
            }

            if(pivot < right-1) {
                stack.push(pivot+1);
                stack.push(right);
            }
        }
    }

    public static void insertSort(int[] array,int left,int right) {
        for (int i = left+1; i <= right; i++) {
            int tmp = array[i];
            int j = 0;
            for (j = i-1; j >=left ; j--) {
                if(array[j] > tmp) {
                    array[j+1] = array[j];
                } else {
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }

    public static void Swap(int[] array,int left,int right) {
        int tmp = array[left];
        array[left] = array[right];
        array[right] = tmp;
    }

    public static int partition1(int[] array,int low,int hight) {
        int tmp = array[low];
        int index = low;
        while(low < hight) {

            while(low < hight && array[hight] >= tmp) {
                hight--;
            }

            while(low < hight && array[low] <= tmp) {
                low++;
            }

            Swap(array,hight,low);
        }
        Swap(array,index,low);
        return hight;
    }

    public static int partition2(int[] array,int low,int hight) {
        int tmp = array[low];

        while(low < hight) {

            while(low < hight && array[hight] >= tmp) {
                hight--;
            }

            array[low] = array[hight];

            while(low < hight && array[low] <= tmp) {
                low++;
            }

            array[hight] = array[low];
        }
        array[low] = tmp;
        return low;
    }

    public static int partition3(int[] array,int low,int hight) {
        int d = low+1;
        int tmp = array[low];

        for (int i = low+1; i <= hight; i++) {
            if(array[i] < tmp) {
                Swap(array,d,i);
                d++;
            }
        }
        Swap(array,d-1,low);
        return d-1;
    }

    public static void quickSort(int[] array,int left,int right) {
        if(left >= right) return;

        /**
         * 利用插入排序的优势优化快排的劣势
         */
        if(right - left+1 < 4) {
            insertSort(array, left, right);
            return;
        }

        /**
         * 三数取中法
         */
        int index = midIndexOf(array,left,right);
        Swap(array,index,left);

        int pivot = partition3(array,left,right);
        quickSort(array,left,pivot-1);
        quickSort(array,pivot+1,right);
    }

    public static int midIndexOf(int[] array,int left,int right) {
        int mid = left + (right - left)/2;

        if(array[left] < array[right]) {
            if(array[mid] < array[left]) {
                return  left;
            } else if(array[mid] > array[right]) {
                return right;
            } else {
                return mid;
            }
        } else {
            if(array[mid] > array[left]) {
                return  left;
            } else if(array[mid] < array[right]) {
                return right;
            } else {
                return mid;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = {8,7,6,1,5,4,10,51,65};
        quickSortSet(array);
        /*quickSortSet(array,0,array.length-1);*/
        System.out.println(Arrays.toString(array));
    }
}
